/**
 * Copyright 2009-2010 - YangJiandong(chunquedong)
 * 
 * This file is part of ChunMap project
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
 * 你可以自由复制、传播本项目的下载包文件，但必须保持其完整性。
 * 我们不用对使用中的风险及由此造成的损失承担任何责任。
 * 详细情况请见《ChunMap许可协议》。

 * 想了解更多有关ChunMap的信息，请访问http://code.google.com/p/chunmap/
 */
package chunmap.model.operate.buffer;


import chunmap.model.elem.CoordSeqEditor;
import chunmap.model.elem.Line;
import chunmap.model.elem.LineSegment;
import chunmap.model.geom.LineString;
import chunmap.model.geom.Ring;
import chunmap.model.geom.Polygon;
import chunmap.model.operate.overlay.OverLayOp;
import chunmap.model.coord.Coordinate2D;
import chunmap.model.coord.Position;

/**
 * @author chunquedong
 * 
 */
public class LineBuffer {
	public Polygon singleLineNoCapBuffer(LineSegment sl, double distance) {
		if (distance <= 0) {
			throw new IllegalArgumentException(
					"very little distance in singleLineNoCapBuffer");
		}
		Line l = sl.toLine();
		double a = Math.atan(l.getVerticalK());// 角度
		double dx = distance * Math.cos(a);
		double dy = distance * Math.sin(a);

		Position p1 = new Coordinate2D(sl.getStartPoint().getX() - dx, sl.getStartPoint()
				.getY()
				- dy);
		Position p2 = new Coordinate2D(sl.getStartPoint().getX() + dx, sl.getStartPoint()
				.getY()
				+ dy);
		Position p3 = new Coordinate2D(sl.getEndPoint().getX() + dx, sl.getEndPoint()
				.getY()
				+ dy);
		Position p4 = new Coordinate2D(sl.getEndPoint().getX() - dx, sl.getEndPoint()
				.getY()
				- dy);

		CoordSeqEditor ls = new CoordSeqEditor();
		ls.addPointToLast(p1);
		ls.addPointToLast(p2);
		ls.addPointToLast(p3);
		ls.addPointToLast(p4);
		ls.addPointToLast(p1);

		Polygon pg = new Polygon(new Ring(ls.toCoordinateSeq()));
		return pg;
	}

	public Polygon lineStringBuffer(LineString ls, double distance) {
		if (distance <= 0) {
			throw new IllegalArgumentException(
					"very little distance in singleLineNoCapBuffer");
		}
		OverLayOp op = new OverLayOp();
		PointBuffer pb = new PointBuffer();
		// 开始点的缓冲
		Polygon pg = pb.createBuffer(ls.firstPoint(), distance);

		for (int i = 0, n = ls.size() - 1; i < n; i++) {
			LineSegment lseg = ls.getLineSegment(i);

			// 线的缓冲区
			Polygon lineBuffer = singleLineNoCapBuffer(lseg, distance);
			Position point = ls.getPoint(i + 1);

			// 结尾点的缓冲
			Polygon pointBuffer = pb.createBuffer(point, distance);

			pg = op.computeUnion(lineBuffer, pg).getGeometry(0);

			// debug
			pg.isValid();

			pg = op.computeUnion(pointBuffer, pg).getGeometry(0);

			// debug
			pg.isValid();
		}

		return pg;
	}
}
